/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \class ETFRun
  \brief The main offline analysis run class. A singleton class.
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2024-06-12
  \date 2024-06-19 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                   </tr>
  <tr>  <td>2024-06-12   <td>Asia Sun    <td>file created                  </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#ifndef ETFRun_h
#define ETFRun_h

#include <list>
#include <mutex>
#include <climits>
#include <semaphore.h>

class TTree;
class TFile;
class ETFTask;
class ETFSource;
class ETFGOnline;
class ETFGanaPre;
class ETFAnalyzer;
class ETFParaManager;

class ETFRun{
public:
  static ETFRun *Instance();
  virtual ~ETFRun();

  virtual void Init();
  virtual void Run(unsigned ev0 = 0, unsigned ev1 = UINT_MAX);
  virtual void Finish();
  virtual void Close();
  virtual void AddTask(ETFTask *t){ fTasks.push_back(t); }
  virtual void Lock(){ kMutex.lock(); } ///< lock mutex
  virtual void Unlock(){ kMutex.unlock(); } ///< unlock mutex
  void SetOnline(){ fIsOnline = true; }
  void OnlineSim(int rest_us); ///< rest_us: nof us to pause per event
  void SetOfflineGUI(ETFGanaPre *gpre){ fGOffline = gpre; }
  bool IsOnline() const{ return fIsOnline; }

  ETFSource *GetSource(){ return fSrc; }
  TTree *GetTree(){ return fTree; }
  const char *GetRootFileName();
  TFile *GetRootFile(){ return fRootFile; }
  ETFAnalyzer *GetAnalyzer() const{ return fAnalyzer; }
  ETFGOnline *GetGOnline() const{ return fGOnline; }
  void SetOnlineClean(); ///< remove the generated rootfile
  virtual unsigned Index() const;
  virtual unsigned CntEv() const;

  static std::mutex kMutex;

private:
  ETFRun();
  static ETFRun *kInstance;

protected:
  virtual void OnlineInit();
  virtual void OfflineInit();
  virtual void OnlineRun();
  virtual void OfflineRun(unsigned ev0, unsigned ev1);

  TFile *fRootFile;
  TTree *fTree;
  ETFParaManager *fpm;
  ETFAnalyzer *fAnalyzer;
  ETFSource *fSrc;
  std::list<ETFTask *> fTasks;

  bool fIsOnline;
  ETFGOnline *fGOnline; ///< online GUI
  ETFGanaPre *fGOffline; ///< offline GUI
};

#endif
